import {
  createContext,
  useContext,
  ReactNode,
  useEffect,
  useMemo,
  useCallback,
  useState,
} from 'react';
import {useIdentityProvider} from './useSIWPIdentity';
import {useActorIdentity} from './useActorIdentity';
import {IdentityModel} from '../db/models/identityModel';

type AuthContextType = {
  isLoggedIn: boolean | undefined;
  logout: () => Promise<void>;
};

export const AuthContext = createContext<AuthContextType | undefined>(
  undefined,
);

export const useAuthProvider = () => {
  const context = useContext(AuthContext);
  if (!context) {
    throw new Error('useAuthProvider must be used within an AuthProvider');
  }
  return context;
};

type AuthProviderProps = {
  children: ReactNode;
};

export function AuthProvider({children}: Readonly<AuthProviderProps>) {
  const [isLoggedIn, setIsLoggedIn] = useState<boolean>();

  const {identityId, identityActor, isInitializing} = useIdentityProvider();
  const {greet} = useActorIdentity();
  const logout = useCallback(async () => {
    if (typeof identityId === 'undefined') {
      setIsLoggedIn(false);
    } else {
      try {
        console.log('logout', identityId);
        const identiyModel = new IdentityModel();
        await identiyModel.deleteIdentityByUid(identityId);
      } catch (error) {}

      setIsLoggedIn(false);
    }
  }, [identityId]);

  useEffect(() => {
    if (isInitializing) {
      return;
    }

    if (
      typeof identityActor === 'undefined' ||
      typeof identityId === 'undefined'
    ) {
      setIsLoggedIn(false);
    } else {
      greet()
        .then(() => {
          setIsLoggedIn(true);
        })
        .catch(error => {
          console.log('greet', error);
          setIsLoggedIn(false);
        });
    }
  }, [identityActor, identityId, isInitializing]);

  const contextValue = useMemo(
    () => ({
      isLoggedIn,
      logout,
    }),
    [isLoggedIn, logout],
  );

  return (
    <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>
  );
}
